#include "PrecompiledHeaders.h"
#include "MenuHighScores.h"

/*
 * Grab state pointers
 */
void MenuHighScores::getStatePointers()
{
    replayManager = (ReplayManager *)findByName("replay_manager");
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////// GAME STATE FUNCTIONS ///////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

MenuHighScores::MenuHighScores()
{
    levelIterator = resources->levels.begin();
	displayingGameScores = false;
}

void MenuHighScores::enter(void)
{
    // set cameras to render through
    resources->render_window->getViewport(0)->setCamera(resources->main_gui_camera);
    if(resources->config->isTriScreen())
    {
        resources->render_window->getViewport(1)->setCamera(resources->left_gui_camera);
        resources->render_window->getViewport(2)->setCamera(resources->right_gui_camera);
    }
    
    // Shows mouse
    CEGUI::MouseCursor::getSingleton().show();
    // Loads the MainMenu.layout script which places all of the main menu buttons on the screen
    CEGUI::Window* HighScoresSheet = CEGUI::WindowManager::getSingletonPtr()->loadWindowLayout("HighScores.layout");
    resources->GUISystem->setGUISheet(HighScoresSheet);
    addEmbeddedWindow("EmbeddedHighScores.layout");
	addEmbeddedWindow("EmbeddedReplays.layout");
    CEGUI::Window* highScoresLabel = CEGUI::WindowManager::getSingletonPtr()->getWindow("EmbeddedHighScores/LabelHighScores");
    highScoresLabel->hide();
    // Sets up the level iterator to retrieve level info
    setLevelDetails();
    resources->scores->setScores(levelIterator->name);
	resources->scores->setReplays(levelIterator->name);
    // Attaches events to the Level Selection Menu buttons
    subscribeImageButton("HighScores/LeftArrow", &MenuHighScores::clickLeftArrow);
    subscribeImageButton("HighScores/RightArrow", &MenuHighScores::clickRightArrow);
	subscribeButton("HighScores/BackButton", &MenuHighScores::clickBackButton, &MenuHighScores::hoverBackButton, &MenuHighScores::offBackButton);
	subscribeImageButton("1Replay", &MenuHighScores::clickReplay1);
	subscribeImageButton("2Replay", &MenuHighScores::clickReplay2);
	subscribeImageButton("3Replay", &MenuHighScores::clickReplay3);
	subscribeImageButton("4Replay", &MenuHighScores::clickReplay4);
	subscribeImageButton("5Replay", &MenuHighScores::clickReplay5);
	// Initialises the menu index
    winIterator = activeWindows.begin();
}

// Calls the enter function to redraw the GUI after being popped back to
void MenuHighScores::resume(void)
{
	enter();
}

bool MenuHighScores::frameStarted(const Ogre::FrameEvent &evt)
{
	if(resources->current_level && resources->current_level->isLoaded())
		resources->current_level->unload();
	return true;
}

void MenuHighScores::exit(void)
{
    CEGUI::MouseCursor::getSingleton().hide();
    CEGUI::WindowManager::getSingleton().destroyAllWindows();
	activeWindows.clear();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////// EVENT HANDLER FUNCTIONS ////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Returns to main menu by popping the level selection menu state
bool MenuHighScores::clickBackButton(const CEGUI::EventArgs &e)
{
    resources->audio->playSource(AUDIO_MENU_CLICK);
	unsubscribeButton("HighScores/BackButton");
    popGameState();
    return true;
}

// Changes the appearance of the back button to signify the mouse hovering over the button
bool MenuHighScores::hoverBackButton(const CEGUI::EventArgs &e)
{
    resources->audio->playSource(AUDIO_MENU_OVER);
    setWindowText("HighScores/BackButton", "[back]");
    return true;
}

// Resets the appearance of the back button to signify the mouse cursor leaving the button area
bool MenuHighScores::offBackButton(const CEGUI::EventArgs &e)
{
    setWindowText("HighScores/BackButton", "back");
    return true;
}

// Retrieves the previous level from the iterator
bool MenuHighScores::clickLeftArrow(const CEGUI::EventArgs &e)
{
    resources->audio->playSource(AUDIO_MENU_CLICK);
    if (displayingGameScores)
    {
        displayingGameScores = false;
		levelIterator = resources->levels.end();
    }
	if (levelIterator == resources->levels.begin())
	{
		displayingGameScores = true;
        setGameDetails();
        resources->scores->setScores("game");
		resources->scores->setReplays("game");
        return true;
	}
	levelIterator--;
    if(levelIterator->isLocked()) {
        return clickLeftArrow(e);
    }
	setLevelDetails();
	resources->scores->setScores(levelIterator->name);
	resources->scores->setReplays(levelIterator->name);
    return true;
}

// Retrieves the next level from the iterator
bool MenuHighScores::clickRightArrow(const CEGUI::EventArgs &e)
{
    resources->audio->playSource(AUDIO_MENU_CLICK);
    if (displayingGameScores)
    {
        displayingGameScores = false;
		levelIterator = resources->levels.begin();
    }
	else
	{
	    levelIterator++;
	    if (levelIterator == resources->levels.end())
	    {	
	        displayingGameScores = true;
	        setGameDetails();
	        resources->scores->setScores("game");
			resources->scores->setReplays("game");
	        return true;
	    }
	}
    if(levelIterator->isLocked()) {
	    return clickRightArrow(e);
	}
	setLevelDetails();
	resources->scores->setScores(levelIterator->name);
	resources->scores->setReplays(levelIterator->name);
    return true;
}

// Sets the details of the level including the image of the level and the name
void MenuHighScores::setLevelDetails()
{
	setWindowImage("HighScores/LevelImage", "set:Levels image:" + levelIterator->hover_image);
	setWindowText("HighScores/LevelName", levelIterator->level_name);
}

// Sets the details of the game signifying that the full game scores are being displayed
void MenuHighScores::setGameDetails()
{
	setWindowImage("HighScores/LevelImage", "set:Levels image:fullgame");
	setWindowText("HighScores/LevelName", "Balls of Fame");
}

bool MenuHighScores::clickReplay1(const CEGUI::EventArgs &e)
{
	loadReplay(CEGUI::WindowManager::getSingleton().getWindow("1Replay")->getText().c_str());
	return true;
}

bool MenuHighScores::clickReplay2(const CEGUI::EventArgs &e)
{
	loadReplay(CEGUI::WindowManager::getSingleton().getWindow("2Replay")->getText().c_str());
	return true;
}

bool MenuHighScores::clickReplay3(const CEGUI::EventArgs &e)
{
	loadReplay(CEGUI::WindowManager::getSingleton().getWindow("3Replay")->getText().c_str());
	return true;
}

bool MenuHighScores::clickReplay4(const CEGUI::EventArgs &e)
{
	loadReplay(CEGUI::WindowManager::getSingleton().getWindow("4Replay")->getText().c_str());
	return true;
}

bool MenuHighScores::clickReplay5(const CEGUI::EventArgs &e)
{
	loadReplay(CEGUI::WindowManager::getSingleton().getWindow("5Replay")->getText().c_str());
	return true;
}

void MenuHighScores::loadReplay(std::string filename)
{
    resources->current_level = &(*levelIterator);
    replayManager->setReplay(filename);
	pushGameState(findByName("replay_manager"));
}

// Plays the audio associated with hovering over a clickable button
bool MenuHighScores::hoverNoise(const CEGUI::EventArgs &e)
{
    resources->audio->playSource(AUDIO_MENU_OVER);
    return true;
}

